﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using NDF.Data.General.Sql;
using NDF.Reflection;
using NDF.Utilities;
using System;
using System.Data;
using System.Data.Linq;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Security.Cryptography;

namespace NDF.Tests.Framework.Reflection
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            User user = new User { ID = 1, Name = "张三" };
            PropertyInfo property = user.GetType().GetProperties().FirstOrDefault(p => p.Name == "ID");
            MethodInfo getMethod = property.GetMethod;

            //DynamicMethod dynamicMethod = new DynamicMethod("_DynamicMethod_GET_" + Guid.NewGuid().ToString("N"), typeof(int), typeof(User).MakeArray());

            //ILGenerator il = dynamicMethod.GetILGenerator();
            //il.Emit(OpCodes.Ldarg_0);
            //il.Emit(OpCodes.Call, getMethod);
            //if (getMethod.ReturnType.IsValueType)
            //{
            //    il.Emit(OpCodes.Box, getMethod.ReturnType);
            //}
            //il.Emit(OpCodes.Ret);

            //Func<User, int> method = dynamicMethod.CreateDelegate(typeof(Func<User, int>)) as Func<User, int>;

            Type methodType = typeof(Func<>).MakeGenericType(getMethod.ReturnType);
            //Func<int> method = getMethod.CreateDelegate(methodType, user) as Func<int>;
            var method = getMethod.CreateDelegate(methodType, user);

            Console.WriteLine(method.DynamicInvoke());
        }


        [TestMethod]
        public void TestMethod2()
        {
            User user = new User { ID = 1, Name = "张三" };
            PropertyInfo property = user.GetType().GetProperties().FirstOrDefault(p => p.Name == "Name");
            MethodInfo setMethod = property.SetMethod;

            //DynamicMethod dynamicMethod = new DynamicMethod("_DynamicMethod_SET_" + Guid.NewGuid().ToString("N"), typeof(string), typeof(User).MakeArray(), typeof(User));

            //ILGenerator il = dynamicMethod.GetILGenerator();
            //il.Emit(OpCodes.Ldarg_0);
            ////if (setMethod.GetParameters()[0].ParameterType.IsValueType)
            ////{
            ////    il.Emit(OpCodes.Unbox_Any, setMethod.GetParameters()[0].ParameterType);
            ////}
            //il.Emit(OpCodes.Call, setMethod);
            //il.Emit(OpCodes.Ret);

            //Action<string> action = dynamicMethod.CreateDelegate(typeof(Action<string>), user) as Action<string>;\

            Action<string> action = setMethod.CreateDelegate(typeof(Action<string>), user) as Action<string>;

            action("李四");
            Console.WriteLine(user.Name);
        }


        [TestMethod]
        public void GetProperties()
        {
            var type = typeof(SqlCommand);
            var properties1 = type.GetAllProperties();
            var properties2 = type.GetRuntimeProperties().ToArray();

            Console.WriteLine(properties1.Length);
            Console.WriteLine(properties2.Length);
        }
    }


    public class User
    {
        public int ID { get; set; }

        public string Name { get; set; }
    }
}
